#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include "kjson.h"


// json解析
KJSON_ERRCODE kjson_parse(KJsonVal val, const char * str){
    assert(val != NULL);
    KJsonContex contex;
    contex.str = str;
    val->type = KJSON_NULL;
    kjson_parse_whitespace(&contex);
    kjson_parse_val(val, &contex);    
}


KJSON_ERRCODE kjson_parse_whitespace(KJsonContex* contex){
    const char* str = contex->str;
    while(*str == ' ' || *str == '\t' || *str == '\r' || *str == '\n') str++;
    contex->str = str;
    return KJSON_PARSE_OK;
}

// 解析值
KJSON_ERRCODE kjson_parse_val(KJsonVal val, KJsonContex* contex){
    const char * str = contex->str;
    switch (str[0])
    {
    case '{':
        // 对象
        break;
    case '[':
        // 数组
        break;
    case 'n':
        // null
        return kjson_parse_null(val, contex);
        break;
    case 't':
        // true
        return kjson_parse_true(val, contex);
        break;
    case 'f':
        // false
        return kjson_parse_false(val, contex);
        break;
    case 0:
        return KJSON_EXPECT_VALUE;
        break;
    
    default:
        return kjson_parse_num(val, contex);
        break;
    }
}


// 解析null
KJSON_ERRCODE kjson_parse_null(KJsonVal val, KJsonContex* contex){
    const char * str = contex->str;
    EXPECT('n', str[0]);    
    if (str[1] == 'u' && str[2] == 'l' && str[3] == 'l')
    {
        val->type = KJSON_NULL;
        str += 4;
        contex->str = str;
        return KJSON_PARSE_OK;
    }else{
        return KJSON_INVALID_SYNTAX;       
    }
}


// 解析true
KJSON_ERRCODE kjson_parse_true(KJsonVal val, KJsonContex* contex){
    const char * str = contex->str;
    EXPECT('t', str[0]);
    if(str[1] == 'r' && str[2] == 'u' && str[3] == 'e'){
        val->type = KJSON_TRUE;
        str += 4;
        contex->str = str;
        return KJSON_PARSE_OK;
    }else{
        return KJSON_INVALID_SYNTAX;
    }
}

// 解析false
KJSON_ERRCODE kjson_parse_false(KJsonVal val, KJsonContex* contex){
    const char* str = contex->str;
    EXPECT('f', str[0]);
    if(str[1] == 'a' && str[2] == 'l' && str[3] == 's' && str[4] == 'e'){
        val->type = KJSON_FALSE;
        str += 5;
        contex->str = str;
        return KJSON_PARSE_OK;
    }else {
        return KJSON_INVALID_SYNTAX;
    }
}

// 解析数字
KJSON_ERRCODE kjson_parse_num(KJsonVal val, KJsonContex* contex){
    const char * str = contex->str;
    char * endp;
    printf("%s\n", str);
    val->data.num = strtod(str, &endp);
    printf("val:%lf\n", val->data.num);
    printf("str: %p, endp: %p", str, endp);
    if(endp == contex->str || endp == NULL){
        val->type = KJSON_NULL;
        return KJSON_INVALID_SYNTAX;
    }else{
        val->type = KJSON_NUM;
        contex->str = endp;
        return KJSON_PARSE_OK;
    }
}


double kjson_get_num(KJsonVal val){
    assert(val->type == KJSON_NUM);
    return val->data.num;
}